package com.dylan.channel.v7.channel;

import com.dylan.channel.v7.NioEventLoop;

import java.nio.channels.ClosedChannelException;
import java.nio.channels.SelectableChannel;
import java.nio.channels.SelectionKey;
import java.nio.channels.ServerSocketChannel;

public abstract class AbstractNioChannel extends AbstractChannel {

    private final SelectableChannel ch;
    volatile SelectionKey selectionKey;

    protected AbstractNioChannel(Channel parent, SelectableChannel ch) {
        super(parent);
        this.ch = ch;
    }

    protected SelectableChannel javaChannel() {
        return this.ch;
    }

    /**
     * Read from underlying {@link SelectableChannel}
     */
    abstract void read();


    @Override
    public NioEventLoop eventLoop() {
        return (NioEventLoop) super.eventLoop();
    }

    protected void doRegister() {
        //在这里把channel注册到单线程执行器中的selector上,注意这里的第三个参数this，这意味着channel注册的时候把本身，也就是nio类的channel
        //当作附件放到key上了，之后会用到这个。
        try {
            SelectableChannel channel = javaChannel();
            int ops = 0;
            if (channel instanceof ServerSocketChannel) {
                ops = SelectionKey.OP_ACCEPT;
            }
            channel.configureBlocking(false);
            selectionKey = javaChannel().register(eventLoop().getSelect(), ops, this);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}
